package org.zjx.operation.impl;

import lombok.Setter;
import org.zjx.entity.ParagraphBean;
import org.zjx.enums.FontType;
import org.zjx.operation.OperationExecutor;
import org.zjx.util.IdentifyFontUtil;
import org.zjx.util.IdentifyTessUtil;
import org.zjx.util.ImageUtil;
import org.zjx.core.IWindow;

import javax.swing.text.AttributeSet;
import java.awt.*;
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;
import java.awt.image.BufferedImage;
import java.util.Collections;
import java.util.List;

public class RobotOperator implements OperationExecutor {
    public static final int MOUSE_LEFT = InputEvent.BUTTON1_DOWN_MASK;
    public static final int MOUSE_RIGHT = InputEvent.BUTTON3_DOWN_MASK;
    @Setter
    protected  IWindow window;
    protected final Robot robot;
    protected Point mousePosition = new Point(0, 0);

    public RobotOperator() {
        try {
            this.robot = new Robot();
            this.robot.setAutoDelay(10);
        } catch (AWTException e) {
            throw new RuntimeException("创建 Robot 失败", e);
        }
    }

    @Override
    public IWindow getWindow() {
        return window;
    }

    @Override
    public BufferedImage screenshot() {
        Rectangle bounds = window.getBounds();
        if (bounds.width == 0 || bounds.height == 0) return null;
        return robot.createScreenCapture(bounds);
    }

    @Override
    public BufferedImage screenshot(Rectangle region) {
        BufferedImage full = screenshot();
        return full.getSubimage(region.x, region.y, region.width, region.height);
    }

    @Override
    public void move(int x, int y) {
        mousePosition = new Point(x, y);
        robot.mouseMove(x, y);
    }


    @Override
    public void gameMove(int x, int y) {

    }


    @Override
    public void gameMove(Rectangle rectangle) {

    }

    @Override
    public void click(int x, int y) {
        move(x, y);
        click(1); // 左键点击
        delay(30);
    }

    @Override
    public void click(int button) {
        int mouseButton = button == 1 ? MOUSE_LEFT : MOUSE_RIGHT;
        pressMouse(mouseButton);
        delay(10);
        releaseMouse(mouseButton);
    }

    @Override
    public void pressMouse(int button) {
        robot.mousePress(button);
    }

    @Override
    public void releaseMouse(int button) {
        robot.mouseRelease(button);
    }

    @Override
    public Point getMousePosition() {
        return null;
    }

    @Override
    public void drag(int fromX, int fromY, int toX, int toY) {
        move(fromX, fromY);
        pressMouse(1);
        delay(100);
        move(toX, toY);
        delay(100);
        releaseMouse(1);
    }

    @Override
    public void press(int keyCode) {
        pressKey(keyCode);
        delay(10);
        releaseKey(keyCode);
    }

    @Override
    public void pressKey(int keyCode) {
        robot.keyPress(keyCode);
    }

    @Override
    public void releaseKey(int keyCode) {
        robot.keyRelease(keyCode);
    }

    @Override
    public void type(String text) {
        for (char c : text.toCharArray()) {
            int keyCode = KeyEvent.getExtendedKeyCodeForChar(c);
            if (keyCode != KeyEvent.CHAR_UNDEFINED) {
                press(keyCode);
                delay(100);
            }
        }
    }

    @Override
    public void hotkey(int... keyCodes) {
        for (int key : keyCodes) {
            robot.keyPress(key);
        }
        delay(50);
        for (int key : keyCodes) {
            robot.keyRelease(key);
        }
    }

    @Override
    public Point findImage(BufferedImage template) {
        BufferedImage screen = screenshot();
        List<Point> points = ImageUtil.matchTemplate(screen, template);
        return points.isEmpty() ? null : points.get(0);
    }

    @Override
    public List<Point> findAllImages(BufferedImage template) {
        BufferedImage screen = screenshot();
        return ImageUtil.matchTemplate(screen, template);
    }

    @Override
    public boolean findColor(Rectangle region, Color targetColor) {
        BufferedImage area = screenshot(region);
        return ImageUtil.haveColor(area, Collections.singletonList(targetColor));
    }

    @Override
    public boolean findColor(Rectangle region, List<Color> targetColors) {
        BufferedImage area = screenshot(region);
        return ImageUtil.haveColor(area, targetColors);
    }

    @Override
    public Color getColor(int x, int y) {
        return robot.getPixelColor(x, y);
    }

    @Override
    public String identifyTess(BufferedImage bufferedImage) {
        return IdentifyTessUtil.tessIdentify(bufferedImage);
    }

    @Override
    public List<ParagraphBean.Word> identifyFont(IWindow window,BufferedImage screen,Rectangle rectangle, List<Color> colors, FontType fontType, int fontHeight,boolean reverse) {
        return IdentifyFontUtil.identifyFont(window,screen,rectangle, colors, fontType, fontHeight,reverse);
    }

    @Override
    public void delay(long milliseconds) {
        try {
            Thread.sleep(milliseconds);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
    }

    @Override
    public Robot getRobot() {
        return robot;
    }
}
